iT邦幫忙

2024 iThome 鐵人賽

DAY 5
0

本系列會使用 vispy 做 3D 的視覺化,因此本文讓讀者熟悉使用 vispy 簡單的畫出各種圖形,方便配合之後的實作。


vispy 是一個 interactive 視覺化的工具,提供了很多 2D/3D 視覺化相關的高階與底層 API,並且可以支援不同的 GUI 程式庫,因此使用起來很方便。

安裝套件,這裡使用 Qt6 為 GUI 的 backend,實際上 vispy 支援其他的例如 tkinter, glfw等:

pip install vispy
# 安裝 pyQt6 作為 GUI backend
pip install PyQt6

根據 API 層級層級的設計,分為幾種:

  • vispy.gloo
  • vispy.visuals
  • vispy.scene
  • vispy.plot

其中 gloo 和 visuals 屬於較為底層的 API ,需要對於 OpenGL / GLSL 有基本的認識,才會比較好上手。而 scene 和 plot 就隱藏了寫 shading language 的需要,由於 GLSL 不是我們想了解重點,且我們只是為了有3D的視覺化,幫助我們理解程式的結果,並不是要產生美美的電腦圖學渲染結果,因此本系列主要會講述和使用 vispy.scene。

首先第一步是建立 canvas 和 canvas 裡的 view:

import sys
from vispy import app, scene

# Create canvas
canvas = scene.SceneCanvas(title="vispy tutorial", keys="interactive", show=True)
# Make color white
canvas.bgcolor = "white"

# Create view and set the viewing camera
view = canvas.central_widget.add_view()
view.camera = "turntable"
view.camera.fov = 50
view.camera.distance = 10

# TODO: Add objects to the view

if __name__ == "__main__":
    if sys.flags.interactive != 1:
        app.run()

執行的話會得到一個空白的框,基本上之後的工作都會依照這樣的 template ,變得只是中間 TODO 的那個部分。

empty

view.camera 代表了 GUI 視窗看場景的相機設定,可以設定不同的模式,例如 turntable, panzoom, fly ,這裡我們使用 turntable(可以旋轉、放大、移動) ,並且設定 fov (視角大小) 和 distance(遠近):

view.camera = "turntable"
view.camera.fov = 50
view.camera.distance = 10

然後我們可以加入物體,例如透過 scene.visuals.Cube 產生一個正方體

import sys
from vispy import app, scene

# Create canvas
canvas = scene.SceneCanvas(title="vispy tutorial", keys="interactive", show=True)
# Make color white
canvas.bgcolor = "white"

# Create view and set the viewing camera
view = canvas.central_widget.add_view()
view.camera = "turntable"
view.camera.fov = 50
view.camera.distance = 10

# Add a red cube
scene.visuals.Cube(color="red", parent=view.scene)

if __name__ == "__main__":
    if sys.flags.interactive != 1:
        app.run()

ball

這裡我們透過 parent=view.scene 來把建立的正方體放到場景裡面,我們也可以換成以下方式:

# scene.visuals.Cube(color="red", parent=view.scene)

cube = scene.visuals.Cube(color="blue", edge_color="black")
view.add(cube)

並且因為前面設置 view.camera = "turntable" ,我們是可以透過滑鼠旋轉,滾輪放大縮小,shift+左鍵移動物體的。

接下來,我們改成建立一個 3D 球,並且在 3D 中移動他的位置。最後,在原點放一個座標 R, G, B 分別代表 X, Y, Z 軸:

# Create sphere
sphere = scene.visuals.Sphere(radius=0.5, color="red", parent=view.scene, shading="smooth")

# Create transform
transform = scene.transforms.MatrixTransform()
transform.translate((1, 1, 1))
# Assign transform to the sphere
sphere.transform = transform

# Create a 3D axis at the origin
scene.visuals.XYZAxis(parent=view.scene)

ball

夠過新增一個 timer 我們還可讓球體動起來,在原本的 code 下面新增這段:

def update(event):
    # Rotate the sphere a bit along the y-axis
    sphere.transform.rotate(1, (0, 1, 0))

timer = app.Timer()
timer.connect(update)
timer.start(0)

就可以得到一個沿著 y 軸旋轉的球體了

animate


上一篇
Day3: 相機與投影總結 (三)
下一篇
Day5: vispy 視覺化 (二) 實作:繪製相機座標
系列文
3D 重建實戰:使用 2D 圖片做相機姿態估計與三維空間重建13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言